﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Net;
using System.Text.RegularExpressions;



namespace Mixr
{
    public partial class AddLocalMedia : Form
    {
        int cur_id;
        string cur_name;
        List<Movie> ChosenMovies = new List<Movie>();
        List<Movie> FoundMovies = new List<Movie>();
        List<Movie> Movies = new List<Movie>();
        
        public AddLocalMedia(int uid, string uname)
        {
            cur_id = uid;
            cur_name = uname;
            InitializeComponent();
        }

        private void AddLocalMedia_Load(object sender, EventArgs e)
        {
       
        }

        public List<string> ExamineDir(string strDir, List<string> Dirs)
        {
            try
            {
                foreach (string strDirName in Directory.GetDirectories(strDir))
                {
                    // Display the directory name.
                    DirectoryInfo Dir = new DirectoryInfo(strDirName);
                    FileInfo[] aviFiles = Dir.GetFiles("*.avi");
                    FileInfo[] mkvFiles = Dir.GetFiles("*.mkv");

                    if (aviFiles.Length > 0 || mkvFiles.Length > 0)
                    {
                        Dirs.Add(strDirName);
                    }
                    ExamineDir(strDirName, Dirs);
                }
            }
            catch { }

            return Dirs;
        }

        //Replace any HTML formatting, with "pretty" characters
        private string cleanText(string line)
        {
            line = line.Replace("&#38;", "&").Replace("&#233;", "é").Replace("&#225;", "á").Replace("&#237;", "í");
            line = line.Replace("&#243;", "ó").Replace("&#250;", "ú").Replace("&#224;", "à").Replace("&#232;", "è");
            line = line.Replace("&#236;", "ì").Replace("&#242;", "ò").Replace("&#249;", "ù").Replace("&#193;", "Á");
            line = line.Replace("&#201;", "É").Replace("&#205;", "Í").Replace("&#211;", "Ó").Replace("&#218;", "Ú");
            line = line.Replace("&#192;", "À").Replace("&#200;", "È").Replace("&#204;", "Ì").Replace("&#210;", "Ò");
            line = line.Replace("&#217;", "Ù").Replace("&#227;", "ã").Replace("&#245;", "õ").Replace("&#241;", "ñ");
            line = line.Replace("&#195;", "Ã").Replace("&#213;", "Õ").Replace("&#209;", "Ñ").Replace("&#226;", "â");
            line = line.Replace("&#234;", "ê").Replace("&#194;", "Â").Replace("&#202;", "Ê").Replace("&#34;", "\"");
            line = line.Replace("&#xE1;", "á").Replace("&#x27;", "'");
            return line;
        }

        //Determine if the IMDB page is a search results page
        //or if it is exactly the movie page - title was sufficient
        public bool IsSearchPage(string q)
        {
            Regex reg = new Regex("<title>(.*?)</title>");
            Match match = reg.Match(q.ToString());
            string tit = match.Groups[1].Value;
            if (tit.StartsWith("IMDb"))
                return true;
            return false;
        }

        //form a movie page (Not a search page) mine the title, year
        //user rating, Plot description, Genres, and DVD cover
        public Movie ParseTitle(string url, DirectoryInfo location)
        {

            Movie movie = new Movie();
            WebRequest request = WebRequest.Create(url);
            WebResponse response = request.GetResponse();

            string data = new System.IO.StreamReader(response.GetResponseStream()).ReadToEnd();
            
            //Parse the Title and Year
            string pat = @"<title>(.*?)\((\d{4}).*?\)</title>";
            Regex reg = new Regex(pat);
            Match match = reg.Match(data);
            movie.title = match.Groups[1].Value;
            movie.year = match.Groups[2].Value;

            //Parse The User Rating
            pat = @"<b>([0-9/\.]+)*.?</b>";
            reg = new Regex(pat);
            string rating = reg.Match(data).Groups[1].Value;
            movie.rating = cleanText(rating);

            //Parse the Genres
            pat = @"<h5>Genre.*?\n.*?\n(<a href=.*?)<a class=";
            reg = new Regex(pat);
            match = reg.Match(data.ToString());
            if (match.Success)
            {
                List<string> genres = new List<string>();
                string temp = match.Groups[1].Value;
                pat = @""">(.*?)</a>";
                reg = new Regex(pat);
                MatchCollection matches = reg.Matches(temp);
                foreach (Match m in matches)
                {
                    genres.Add(cleanText(m.Groups[1].Value));
                }
                movie.genres = genres;
            }
            
            //Parse the Plot
            pat = @"<h5>Plot.*?\n.*?\n(.*?)\n?<";
            reg = new Regex(pat);
            movie.description = cleanText(reg.Match(data.ToString()).Groups[1].Value.Trim());

            //Parse the Movie DVD Cover (better quality)
            if (!data.ToString().Contains("http://ia.media-imdb.com/media/imdb/01/I/37/89/15/10.gif"))
            {
                pat = @"<a name=""poster"".*?src=""(.*?)""";
                reg = new Regex(pat);
                string covLink = reg.Match(data.ToString()).Groups[1].Value;

                WebRequest requestPic = WebRequest.Create(covLink);
                WebResponse responsePic = requestPic.GetResponse();

                Image webImage = Image.FromStream(responsePic.GetResponseStream());

                movie.cover = webImage;
            }

            //get the full path to the files within the directory
            //will take the last avi or mkv file within the folder
            //it is expected there will only be one file within each folder
            FileInfo[] aviFiles = location.GetFiles("*.avi");
            FileInfo[] mkvFiles = location.GetFiles("*.mkv");

            for (int x = 0; x < aviFiles.Length; x++)
            {
                string loc = location.ToString() + "\\" + aviFiles[x].ToString();
                System.Diagnostics.Debug.WriteLine(loc);
                movie.locationString = loc;
            } 

            for (int x = 0; x < mkvFiles.Length; x++)
            {
                string loc = location.ToString() + "\\" + mkvFiles[x].ToString();
                System.Diagnostics.Debug.WriteLine(loc);
                movie.locationString = loc;
            }

            movie.cur_id = cur_id;
            //scrub the movie information for single and double quotes that would
            //interrupt the SQL entry
            Movie clean = cleanup(movie);
            return clean;

        }

        public string cleanforSQL(string broken){
            if (broken != null)
            {
                broken = broken.Replace("'", "''");
                broken = broken.Trim();
            }
            return broken;
        }

        //clean all strings in a Movie object
        public Movie cleanup(Movie mov){
            Movie movie = mov;

            movie.title = cleanforSQL(movie.title);
            movie.locationString = cleanforSQL(movie.locationString);
            movie.quality = cleanforSQL(movie.quality);
            movie.rating = cleanforSQL(movie.rating);
            movie.year = cleanforSQL(movie.year);
            movie.director = cleanforSQL(movie.director);
            movie.writer = cleanforSQL(movie.writer);
            movie.description = cleanforSQL(movie.description);
            movie.url = cleanforSQL(movie.url);

            return movie;
        }

        //user clicks the "OK" button, to begin parsing
        private void button1_Click(object sender, EventArgs e)
        {
            progressBar1.Enabled = true;
            progressBar1.Visible = true;

        
            //Content are Moives
            if (MoviesRadio.Checked)
            {

                List<string> Dirs = new List<string>();
                //Loop through all Directories Recursively searching for Movies
                Dirs =  ExamineDir(folderBrowseText.Text, Dirs);

                string data = "";

                //For all folders found, search the directory name on IMDB
                //TODO: check if directory has a movie file within it
                int value = Dirs.Count / 100;
                foreach(string name in Dirs)
                {
                    progressBar1.Value += value;
                    DirectoryInfo dr1 = new DirectoryInfo(@name);
                    string NewName = dr1.Name.Replace(" ", "+");
                    string strUrl = "http://www.imdb.com/find?s=tt&q=" + NewName;

                    try
                    {
                        WebRequest request = WebRequest.Create(strUrl);
                        WebResponse response = request.GetResponse();
                        data = new System.IO.StreamReader(response.GetResponseStream()).ReadToEnd();
                    }
                    catch
                    {
                        MessageBox.Show("Add Media requires an internet connection");
                        this.Close();
                        new MixrWindow(cur_id, cur_name).Show();
                        break;
                    }
                    
                    
                    

                    //If the Page is a results page, rather than an actual movie page
                    //Populate a list of possible movie choices
                    if (IsSearchPage(data))
                    {
                        List<Movie> choices = new List<Movie>();
                        
                        Regex PopularTitles = new Regex(@"<b>Popular Titles</b>(.*)");
                        Regex ExactMatches = new Regex(@"<b>Titles \(Exact Matches\)</b.(.*)");
                        Match ExactMatch = ExactMatches.Match(data);
                        Match PopularMatch = PopularTitles.Match(data);
                        string line = "";
                        string url = "";

                        //if there are "popular" or "exact" matches for the movie title
                        //Generate a list of all possibilities
                        if (PopularMatch.Success || ExactMatch.Success)
                        {
                            if (PopularMatch.Success)
                                line = PopularMatch.Groups[1].Value;
                            else
                                line = ExactMatch.Groups[1].Value;
                            Regex titles = new Regex(@"(<a href=.*?)</td></tr>");
                            MatchCollection matches = titles.Matches(line);

                            foreach (Match m in matches)
                            {
                                line = m.Groups[1].Value;
                                line = cleanText(line);
                                //Match for the URL
                                Regex reg = new Regex(@"<a href=""(.{17})");
                                url = reg.Match(line).Groups[1].Value;

                                //Match for smal DVD Cover
                                string pat = @"<img src=""(.*?)""";
                                reg = new Regex(pat);
                                string cover = reg.Match(line).Groups[1].Value;
                                Match coverMatch = reg.Match(line);

                                //Match for title of movie and year
                                reg = new Regex(@";"">(&#34;|""|&#x22;)?(['&,áéíóúàèìòùÁÉÍÓÚÀÈÌÒÙãÃõÕâêÊÂñÑA-Za-z0-9 :\(\)!]*)(&#34;|""|&#x22;)?</a>\s*?\((\d{4}).*?\)");
                                Match mat = reg.Match(line);

                                //if able to parse the title, and insert into a list of possible matches
                                if (mat.Success)
                                {
                                    string Title = mat.Groups[2].Value;
                                    string Year = mat.Groups[4].Value;

                                    Image webImage = global::Mixr.Properties.Resources.mixr;

                                    if (coverMatch.Success)
                                    {
                                        WebRequest requestPic = WebRequest.Create(cover);
                                        WebResponse responsePic = requestPic.GetResponse();

                                        webImage = Image.FromStream(responsePic.GetResponseStream());
                                    }

                                    Movie movie = new Movie(cur_id, Title, Year, url, webImage, dr1);
                                    choices.Add(movie);
                                }

                            }

                            //Popup a list of possible matches for the user to choose the exact title to match
                            ChooseMedia chosen = new ChooseMedia(this, choices);
                            if (chosen.ShowDialog() == DialogResult.OK)
                            {
                                ChosenMovies.Add(chosen.getMovie());
                            }
                        }
                    }

                    else
                    {
                        Movie movie = new Movie(strUrl, dr1);
                        FoundMovies.Add(movie);
                    }

                    listView1.Items.Add(name);
                }

                //Loop through all movies that the program knew the specific moives
                foreach (Movie movie in FoundMovies)
                {
                    Movie final = ParseTitle(movie.getUrl(), movie.location);
                    Movies.Add(final);
                }

                //Loop through all movies that the program didn't know the specific movie
                foreach (Movie movie in ChosenMovies)
                {
                    string url = "http://www.imdb.com" + movie.getUrl();
                    Movie final = ParseTitle(url, movie.location);
                    Movies.Add(final);
                }

                //Loop through all movies, and add them to the database
                foreach (Movie movie in Movies)
                {
                    movie.DumpMovieToDatabase();
                }

                this.Close();
                new MixrWindow(cur_id, cur_name).Show();
                System.Diagnostics.Debug.WriteLine("done");
            }

            else if (TelevisionRadio.Checked)
            {
                //
                //TODO: Create television parsing from the TVDB
                //
            }

            else if (MusicRadio.Checked)
            {
                //
                //TODO: create Music parsing from ???
                //
            }

            else
            {
                this.Close();
                new MixrWindow(cur_id, cur_name).Show();
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            LocalMediaBrowse.ShowDialog();
            folderBrowseText.Text = LocalMediaBrowse.SelectedPath;
        }

        private void AddLocalMedia_Load_1(object sender, EventArgs e)
        {

        }
    }
}
